﻿namespace Guia.Elements
{
    using System;
    using System.Diagnostics.Contracts;
    using System.Windows.Automation;
    using Guia.Core;
    using Guia.Locator;

    /// <summary>
    /// This abstract class represents an abstract element for any menu-items.
    /// </summary>
    public abstract class AbstractMenuItem : UiElement
    {
        /// <summary>
        /// Initializes a new instance of the AbstractMenuItem class. 
        /// </summary>
        /// <param name="automationElement">The AutomationElement representating this AbstractMenuItem.</param>
        /// <exception cref="ArgumentNullException">Thrown when the given AutomationElement is null</exception>
        protected AbstractMenuItem(AutomationElement automationElement) : base(automationElement)
        {
        }

        /// <summary>
        /// Provides access to MenuItems belonging to this MenuItem (Submenu).
        /// </summary>
        /// <param name="automationId">The automationId of the desired MenuItem.</param>
        /// <returns>A MenuItem that belongs to this MenuItem.</returns>
        /// <exception cref="ElementNotFoundException">This exception is thrown when there exists no MenuItem with the given automationId.</exception>
        /// <exception cref="ArgumentException">This exception is thrown when the automationId is null or empty</exception>
        public MenuItem this[string automationId]
        {
            get
            {
                Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(automationId));
                return this.GetMenuItem(automationId);
            }
        }

        /// <summary>
        /// Get all MenuItem instances belonging to this MenuItem (Submenu).
        /// </summary>
        /// <returns>An array of MenuItems.</returns>
        public virtual MenuItem[] GetAllMenuItems()
        {
            SearchCondition searchCondition = SearchCondition.FromAutomationCondition(Condition.TrueCondition);
            searchCondition.Scope = TreeScope.Children;
            return GetAll<MenuItem>(searchCondition);
        }

        /// <summary>
        /// Get the MenuItem with the given automationId.
        /// </summary>
        /// <param name="automationId">The automationId of the MenuItem.</param>
        /// <returns>A MenuItem.</returns>
        /// /// <exception cref="ArgumentException">This exception is thrown when the automationId is null or empty</exception>
        protected virtual MenuItem GetMenuItem(string automationId)
        {
            Contract.Requires(!string.IsNullOrEmpty(automationId));
            SearchCondition searchCondition = SearchCondition.FromAutomationCondition(Condition.TrueCondition);
            searchCondition.Scope = TreeScope.Children;
            searchCondition.And(SearchCondition.ByAutomationId(automationId));
            return Get<MenuItem>(searchCondition);
        }
    }
}
